<?php

namespace SunAdmin\Subscribe;


use SunAdmin\Service\ConsoleInfoPrinter;
use SunAdmin\Service\DataDictionaryService;
use SunAdmin\Service\Ws\FdUidBinding;
use SunAdmin\Task\TimerTaskManage;
use Swoole\Coroutine;
use think\Event;
use think\facade\Db;
use think\facade\Log;


class SystemEventSubscribe
{
    public function onAppInit($event)
    {

    }

    public function onSwooleInit($event)
    {
        //logo
        $logo = "
  ______                     ___         _           _        
 / _____)                   (___)       | |         (_)       
( (____    _   _   ____    /_____\    __| |  ____    _   ____  
 \____ \  | | | | |  _ \  |  ___  |  / _  | |    \  | | |  _ \ 
 _____) ) | |_| | | | | | | |   | | ( (_| | | | | | | | | | | |
(______/  |____/  |_| |_| |_|   |_|  \____| |_|_|_| |_| |_| |_|
";
        echo $logo;
        
        try {
            $mysqlVersion = Db::query('SELECT VERSION() as version')[0]['version'];
        } catch (\Exception $e) {
            $mysqlVersion = "Mysql异常," . $e->getMessage();
        }
        
        $banner = new ConsoleInfoPrinter(63);
        $banner->setTitle([
            '欢迎使用 SunAdmin 通用后台管理框架',
            'https://www.lingyier.com | sunjinglong@lingyier.com',
        ]);
        $banner->addInfo('项目名称', env('PROJECT_NAME', 'SunAdmin'));
        $banner->addInfo('Php 版本', phpversion());
        $banner->addInfo('Mysql 版本', $mysqlVersion);
        $banner->addInfo('Swoole 版本', phpversion('swoole'));
        $banner->addInfo('Thinkphp版本', app()->version());
        $banner->addInfo('SunAdmin版本', '1.0.0');
        
        // 安全获取 Swoole 配置
        $httpConf = config("swoole.http", []);
        if (!empty($httpConf)) {
            $banner->addInfo('Swoole http启用状态', ($httpConf['enable'] ?? false) ? '开启' : '关闭');
            $banner->addInfo('Swoole http监听地址', $httpConf['host'] ?? 'localhost');
            $banner->addInfo('Swoole http监听端口', $httpConf['port'] ?? 8000);
            $banner->addInfo('Swoole worker进程数', $httpConf['worker_num'] ?? 1);
        }
        
        $wsConf = config("swoole.websocket", []);
        if (!empty($wsConf)) {
            $banner->addInfo('Websocket启用状态', ($wsConf['enable'] ?? false) ? '开启' : '关闭');
        }
        
        $rpcConf = config("swoole.rpc.server", []);
        if (!empty($rpcConf)) {
            $banner->addInfo('Rpc 启用状态', ($rpcConf['enable'] ?? false) ? '开启' : '关闭');
            if ($rpcConf["enable"] ?? false) {
                $banner->addInfo('rpc监听地址', $rpcConf['host'] ?? 'localhost');
                $banner->addInfo('rpc监听端口', $rpcConf['port'] ?? 9000);
                $banner->addInfo('rpc worker进程数', $rpcConf['worker_num'] ?? 1);
            }
        }
        
        $banner->render();

        // 清除所有WebSocket连接类型的fd绑定数据，确保启动时状态干净
        try {
            FdUidBinding::clearAllBindings();
            Log::info("WebSocket绑定数据清理完成");
        } catch (\Throwable $e) {
            Log::error("WebSocket绑定数据清理失败: " . $e->getMessage());
        }
        //预热数据字典
        DataDictionaryService::updateCacheData();
    }

    public function onWorkerStart($v)
    {
        // 检查是否启用了 Swoole
        if (!extension_loaded('swoole')) {
            return;
        }
        
        // 启动统一定时任务调度器
        try {
            (new TimerTaskManage())->start();
        } catch (\Exception $e) {
            Log::error('定时任务调度器出现异常: ' . $e->getMessage());
        }
    }

    public function onHttpRun($event)
    {
    }

    public function onLogWrite()
    {

    }

    public function onLogRecord($event)
    {
        Coroutine::create(function () use ($event) {
            fwrite(STDOUT, "[{$event->type}]" . '--' . $event->message . "\n");
        });
    }

    public function subscribe(Event $event)
    {
        $event->listen('AppInit', [$this, 'onAppInit']);
        $event->listen('swoole.init', [$this, 'onSwooleInit']);
        $event->listen('swoole.workerStart', [$this, 'onWorkerStart']);
        $event->listen('HttpRun', [$this, 'onHttpRun']);
        $event->listen('LogWrite', [$this, 'onLogWrite']);
        $event->listen('LogRecord', [$this, 'onLogRecord']);
    }
}